/**
  ******************************************************************************
  * @file    ADC文件
  * @author  jin yang chao
  * @version V1.0.0
  * @date    2019.03.25
  * @brief   DDC采样控制程序 采样文件
  * @attention
  *
  ******************************************************************************
  */
#include "bsp_ads8681.h"
#include <rtthread.h>
#include "spi.h"

uint8_t busy_flag = IDLE_STATUS;
SPI_HandleTypeDef SpiHandle2;
TIM_HandleTypeDef htim3;
extern uint8_t start_state; //开始采集状态，1开始，0停止
extern uint8_t calibrate_state;//校准状态，为非0时是在校准。
//static uint32_t  sum_value = 0;
uint16_t ADC8681_value[2050] = {0};
static uint16_t max_num = 0,min_num = 0;


void TIM3_delay_init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig;//定时器时钟配置
  TIM_MasterConfigTypeDef sMasterConfig;//定时器主从模式配置
 
  htim3.Instance = TIM3;//50us计时中断一次
  htim3.Init.Prescaler = 1000-1;               /* 定时器分频 */
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP; /* 向上计数模式 */
  htim3.Init.Period = 5-1;                     /* 自动重装载值 */
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  HAL_TIM_Base_Init(&htim3);
	
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig);
	
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;//从模式,设置是否使用定时器的被动触发。
  HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig);
	rt_kprintf("TIM3_init\r\n");
}


void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
 
  if(tim_baseHandle->Instance==TIM3)
  {
  /* USER CODE BEGIN TIM3_MspInit 0 */
 
  /* USER CODE END TIM3_MspInit 0 */
    /* TIM3 clock enable */
    __HAL_RCC_TIM3_CLK_ENABLE();
 
    /* TIM3 interrupt Init */
    HAL_NVIC_SetPriority(TIM3_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(TIM3_IRQn);
  /* USER CODE BEGIN TIM3_MspInit 1 */
 
  /* USER CODE END TIM3_MspInit 1 */
  }
}

void TIM3_IRQHandler(void)
{
  HAL_TIM_IRQHandler(&htim3);
}


// 定时器更新中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	uint16_t value = 0;
	static uint16_t max_value = 0,min_value = 0;
	static uint16_t num = 0;

	// 判断是定时器3发生的中断
	if(htim->Instance == TIM3)
	{
	
     //spi读取8681数据
			//if(calibrate_state > 0 || start_state == 1)
				 if(busy_flag == 0) 
			{
				if(num == 2050)
				{
				  num = 0;
//					max_num = 0;
//					min_num = 0;
				}
				//写指令
//				ADS8689_ENABLE;//cs拉低
//			  ads8689_read_write(0x0000);
//		    ads8689_read_write(0);
//			  ADS8689_DISABLE;//cs拉高
			 	
				
				//读数据
				ADS8689_ENABLE;//cs拉低
				value = ads8689_read_write(0) ;
				ADS8689_DISABLE;//cs拉高
	 			ADC8681_value[num] = value;
			//rt_kprintf("value:%d\r\n",value);
				if(min_num == num || max_num == num)
				{			
					//压力值数组循环一次后覆盖
					if(min_num == num)
					{
					  //min_num = 0;
						min_value = value;
						
					}
					else if(min_num == num)
					{
					 //min_num = 0;
						max_value = value;
					}				
			 }
			else
			{
				if(value < min_value)//判断最小值
				{
					min_value = value;
					//rt_kprintf(" min_value:%d\r\n",min_value);
					min_num = num;
					
				}
				if(value > max_value)//判断最大值
				{
					max_value = value;
					min_num = num;
				}
			}
				num++;
			 //rt_kprintf(" num:%d\r\n",num);
			}
//		 if(busy_flag == 0) 
//			{
//				if(num == 130)
//				{
//				  num = 0;
////					max_num = 0;
////					min_num = 0;
//				}
//				//写指令
//				ADS8689_ENABLE;//cs拉低
//			  ads8689_read_write(0x0000);
//		    ads8689_read_write(0);
//			  ADS8689_DISABLE;//cs拉高
//			 	
//				
//				//读数据
//				ADS8689_ENABLE;//cs拉低
//				value = ads8689_read_write(0);
//				ADS8689_DISABLE;//cs拉高
//				ADC8681_value[num] = value;
//				if(min_num == num || min_num == num)
//				{			
//					//压力值数组循环一次后覆盖
//					if(min_num == num)
//					{
//					  //min_num = 0;
//						min_value = value;
//						
//					}
//					else if(min_num == num)
//					{
//					 //min_num = 0;
//						max_value = value;
//					}				
//			 }
//			else
//			{
//				if(value < min_value)//判断最小值
//				{
//					min_value = value;
//					//rt_kprintf(" min_value:%d\r\n",min_value);
//					min_num = num;
//					
//				}
//				if(value > max_value)//判断最大值
//				{
//					max_value = value;
//					min_num = num;
//				}
//			}
//				num++;
//			 //rt_kprintf(" num:%d\r\n",num);
//			}
	}
}


/**
  * @brief  adc 外设配置 
  * @param  None
  * @param  None   
  * @return None
  */

void adc_spi_init(void)
{
	__HAL_SPI_DISABLE(&SpiHandle2);/* 先禁止SPI  */
	
	SpiHandle2.Instance               = SPI2;
	SpiHandle2.Init.Direction = SPI_DIRECTION_2LINES;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
	SpiHandle2.Init.Mode = SPI_MODE_MASTER;		        //设置SPI工作模式:主机模式
	SpiHandle2.Init.DataSize = SPI_DATASIZE_16BIT;		  //数据位长度 ： 16位
	SpiHandle2.Init.CLKPolarity = SPI_POLARITY_LOW;    //时钟下降沿采样数据
	SpiHandle2.Init.CLKPhase = SPI_PHASE_1EDGE;        //时钟的第1个边沿采样数据
	SpiHandle2.Init.NSS = SPI_NSS_SOFT;                //片选控制方式：软件控制
	
	/* 设置波特率预分频系数 SPI_BaudRatePrescaler_8 ，实测SCK周期 96ns, 10.4MHz */
	SpiHandle2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;		
	SpiHandle2.Init.FirstBit = SPI_FIRSTBIT_MSB;	//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
	SpiHandle2.Init.CRCPolynomial = 7;	//CRC值计算的多项式
	HAL_SPI_Init(&SpiHandle2);
	
	__HAL_SPI_ENABLE(&SpiHandle2);/* 使能SPI  */
	
}

/**
  * @brief  ads8689_read_write(uint16_t ch)
  * @param  data ：要发送的数据 
  * @return 返回收到的数据
  */
uint16_t ads8689_read_write(uint16_t data)
{
	/* 等待发送缓冲区为空，TXE 事件 */

//  uint16_t pdata;
	uint16_t RxData;
//  pdata = (data | 0x0080) << 8;

// /*硬件通道，发送的数据，接收的数据，数据长度，超时时间*/
//	uint8_t RxData;
    HAL_SPI_TransmitReceive(&SpiHandle2,(uint8_t*)&data,(uint8_t*)&RxData,1,0xff);
	  RxData=RxData;
    return RxData;
}
/**
  * @brief  ads8689_int()
  * @param  8689的初始化
  * @return 
  */
void ads8689_int(void)
{
	uint16_t id;
	
	//adc_spi_gpio();
	adc_spi_init();
	
	ads8689_write_cmd(0xd014,0x0008);
	in_rang_select(INT_15VREF);
	conv_state();
	device_id(&id);
}
/**
  * @brief  delay_5us()
  * @param  count ：要延迟的时间
  * @retval 
  */
void delay_us(uint16_t count)
{ uint16_t i=19*count;
	while(i--)
	{
		__ASM("NOP");
	}
}
/**
  * @brief  ads8689_write_cmd(uint16_t cmd_hi,uint16_t cmd_li)
  * @param  li_data ：要发送的低位数据
  * @param  hi_data ：要发送的高位数据
  * @return 返回收到的数据
  */
uint8_t  ads889_busy_set(uint8_t busy)
{
	uint8_t ret = 0;
	switch(busy)
	{
		/*空闲状态*/
		case IDLE_STATUS:
			busy_flag = IDLE_STATUS;
			ADS8689_DISABLE;
			break;
		/*忙状态*/
		case BUSY_STATUS:
			busy_flag = BUSY_STATUS;
			ADS8689_ENABLE;
			break;
		default:
			ret = 1;
		break;
	}
	return ret;
}
/**
  * @brief  uint8_t get_busy_status(void)
  * @param  无
  * @return 返回 busy_flag IDLE_STATUS / BUSY_STATUS
  */
uint8_t get_busy_status(void)
{
	return busy_flag;
}
/**
  * @brief  ads8689_write_cmd(uint16_t cmd_hi,uint16_t cmd_li)
  * @param  li_data ：要发送的低位数据
  * @param  hi_data ：要发送的高位数据
  * @return 成功与失败 0：设置成功 1：设置失败
  */
uint8_t ads8689_write_cmd(uint16_t cmd_hi,uint16_t cmd_li)
{

	uint8_t ret;
	/*ADS8986使能*/
	if(ads889_busy_set(BUSY_STATUS)) //设置成功为 0
	{
    ret = 1;
		return ret;
	}
	else{
		ads8689_read_write(cmd_hi);
		ads8689_read_write(cmd_li);
    ret = 0;
	}
  if(ads889_busy_set(IDLE_STATUS)) //设置成功为 0
	{
		ret = 1;
		return ret;
	}

   return ret;
}
/**
  * @brief  conv_state(void)
  * @param  无
  * @param  无
  * @return 成功与失败 0：设置成功 1：设置失败
  */
uint8_t conv_state(void)
{
  uint8_t ret;
	/*ADS8986使能*/
	if(ads889_busy_set(BUSY_STATUS)) //设置成功为 0
	{
    ret = 1;
		return ret;
	}
	else{
	 ret =0;
   delay_us(5);
	}
  if(ads889_busy_set(IDLE_STATUS)) //设置成功为 0
	{
		ret = 1;
		return ret;
	}

  return ret;
}
/**
  * @brief  ads8689_read_data(uint16_t hi_data,uint16_t li_data,uint32_t * result)
  * @param  li_data ：要发送的低位数据
  * @param  hi_data ：要发送的高位数据
  * @param  result ：寄存器读到的结果通过指针传出
  * @return 成功与失败 0：设置成功 1：设置失败
  */
uint8_t ads8689_read_data(uint16_t hi_data,uint16_t li_data,uint32_t * result)
{
	uint8_t ret;
	uint32_t value;
	/*ADS8986使能*/
	if(ads889_busy_set(BUSY_STATUS)) //设置成功为 0
	{
    ret = 1;
		return ret;
	}
	else{
		value = ads8689_read_write(hi_data);
		value =value<<16;
		value += ads8689_read_write(li_data);
		*result = value;
		ret = 0;
	}
  if(ads889_busy_set(IDLE_STATUS)) //设置成功为 0
	{
		ret = 1;
		return ret;
	}

  return ret;
}

/**
  * @brief  uint8_t device_id(uint16_t *id)
  * @param  id ：寄存器读到的结果通过指针传出
  * @return 成功与失败 0：设置成功 1：设置失败
  */
uint8_t device_id(uint16_t *id)
{
	uint8_t ret = 0;
	uint32_t reslut;
	if(ads8689_write_cmd(0xc800,0x0000))
	{
		ret =1;
		return ret;
	}
	if(ads8689_read_data(0,0,&reslut))
	{
		ret =1;
		return ret;
	}
	rt_kprintf(" ADS8681 ID:%X\r\n",reslut>>16); 
	*id = (reslut>>16);
	return ret;
}


/**
  * @brief  uint8_t measured_value(uint32_t *reslut)
  * @param  reslut ：寄存器读到的结果通过指针传出
  * @param  num ：采集次数
  * @return 成功与失败 0：设置成功 1：设置失败
2023.7.9改
  */
uint8_t measured_value(uint32_t *reslut,uint16_t num)
{
//	uint16_t set_value = PAR_EN | RANGE_INC | IN_ACTIVE_ALARM_INCL
//	                     |VDD_ACTIVE_ALARM_INCL|DEVICE_ADDR_INCL;
//	uint16_t get_reslut[255]={0};
	uint32_t value =0;
	uint8_t ret =0,i = 0;
    uint16_t n = 0;
	busy_flag = 1;
//	for(i = 0; i < num; i ++)
//	{
//		for(n = 0;n < 130;n ++)
//		{
//			value += ADC8681_value[n];
//		}
//		value = value - ADC8681_value[min_num] -ADC8681_value[max_num];
//		value = value>>7;
//		//rt_kprintf(" value:%d\r\n",value);
//		get_reslut[i] = value;
//		//rt_kprintf(" 1_value:%d\r\n",value);
//		rt_thread_mdelay(5);
//	}
	for(n = 0;n < 2050;n ++)
		{
			value += ADC8681_value[n];
			//rt_kprintf(" ADC8681_value[n]:%d\r\n",ADC8681_value[n]);
		}
		value = value - ADC8681_value[min_num] -ADC8681_value[max_num];
		value = value>>11;
	busy_flag = 0;
//	value =0;
//  for(i = 0; i < num;i ++)
//	{
//		value += get_reslut[i]; 
//	}
	//rt_kprintf(" measured_value:%d\r\n",value); 
	rt_enter_critical();
  //*reslut = value/num;
	*reslut = value;
	rt_exit_critical();
	
  return ret;
}


///**
//  * @brief  uint8_t measured_value(uint32_t *reslut)
//  * @param  reslut ：寄存器读到的结果通过指针传出
//  * @param  num ：采集次数
//  * @return 成功与失败 0：设置成功 1：设置失败
//  */
//uint8_t measured_value(uint32_t *reslut,uint16_t num)
//{
////	uint16_t set_value = PAR_EN | RANGE_INC | IN_ACTIVE_ALARM_INCL
////	                     |VDD_ACTIVE_ALARM_INCL|DEVICE_ADDR_INCL;
//	uint16_t get_reslut[255]={0};
//	uint32_t value =0;
//	uint8_t ret =0;
//	uint16_t i = 0;
//	
//	for(i = 0; i < num; i ++)
//	{
//		if(ads8689_write_cmd(0x0000,0))
//		{
//			ret =1;
//			return ret;
//		}
//		if ( ads8689_read_data(0,0,&value))
//		{
//			ret =1;
//			return ret;
//		}
//		value = ((value >>16) & 0x0000ffff);
//		get_reslut[i] = value;
//		
//		rt_thread_mdelay(5);
//	}
//	value =0;
//  for(i = 0; i < num;i ++)
//	{
//		value += get_reslut[i]; 
//	}
////	rt_kprintf(" measured_value:%d\r\n",value/num); 
//	rt_enter_critical();
//  *reslut = value/num;
//	rt_exit_critical();
//	
//  return ret;
//}

//uint8_t measured_value(uint32_t *reslut,uint16_t num)
//{
////	uint16_t set_value = PAR_EN | RANGE_INC | IN_ACTIVE_ALARM_INCL
////	                     |VDD_ACTIVE_ALARM_INCL|DEVICE_ADDR_INCL;
//	uint32_t value =0;
//	uint8_t ret =0;
//	
//	if(ads8689_write_cmd(0x0000,0))
//		{
//			ret =1;
//			return ret;
//		}
//	if ( ads8689_read_data(0,0,&value))
//		{
//			ret =1;
//			return ret;
//		}
//	value = ((value >>16) & 0x0000ffff);
////	rt_kprintf(" measured_value:%d\r\n",value/num); 
//	rt_enter_critical();
//  *reslut = value;
//	rt_exit_critical();
//	
//  return ret;
//}

/**
  * @brief  uint8_t in_rang_select(uint16_t cmd)
  * @param  cmd ：INT_30VREF (3*vref ) INT_25VREF (2.5*vref )
                  INT_15VREF (1.5*vref ) INT_125VREF (1.25*vref )
  * @return 成功与失败 0：设置成功 1：设置失败
  */
uint8_t in_rang_select(uint16_t cmd)
{
	uint8_t ret =0;
	uint32_t reslut;
  if(ads8689_write_cmd(0xd014,cmd))
	{
		ret =1;
		return ret;
	}
	if(ads8689_write_cmd(0xc814,0))
	{
		ret =1;
		return ret;
	}
	if ( ads8689_read_data(0,0,&reslut))
	{
		ret =1;
		return ret;
 	}
	else
	{
		if ((reslut>>16) == cmd)
		{
		 ret =0;
		 return ret;
		}
		else
		{
			ret =1;
		  return ret;
		}
	}
	return ret;
}









